#ifndef SERVER_CLIENTS_CLEANER_H_
#define SERVER_CLIENTS_CLEANER_H_
#include "../SocketsAndThreads/socket.h"
#include "../SocketsAndThreads/thread.h"
#include "../SocketsAndThreads/mutex.h"
#include "../Utils/directoryHandler.h"
#include "server_client_thread.h"
#include "../Utils/Decoder.h"
#include "../Utils/md5.h"
#include "../Utils/index.h"
#include <ctime>
#include <vector>
#include <map>
#include <log4cpp/Category.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/SimpleLayout.hh>
using namespace std;

//Variable global utilizada para loggear a un archivo
extern log4cpp::Category& category;

class ClientsCleaner: public Thread {
private:
	//Vector con los hilos de los clientes conectados
	vector<ClientThread*>* clients_threads;
	//Tiempo maximo permitido de inactivdad
	unsigned int max_inactive_time;
	//Tiempo para buscar clientes inactivos
	unsigned int cleaner_time;
	//Mutex que comparten todos los clientes
	Mutex* all_clients_mutex;
	//Bytes almacenados hasta el momento en total
	unsigned int* stored_bytes;
	//Tiempo de inicio del servidor
	unsigned int start_time;

	//Determina si un thread se considera inactivo
	bool IsInactive(ClientThread* ct) {
		unsigned int inactive_time = time(0) - ct->last_interaction;
		return (inactive_time > max_inactive_time);
	}

public:

	ClientsCleaner(vector<ClientThread*>* v, unsigned int s, unsigned int c,
			Mutex* m, unsigned int start_time, unsigned int* stored_bytes) {
		this->start_time = start_time;
		this->stored_bytes = stored_bytes;
		clients_threads = v;
		max_inactive_time = s;
		cleaner_time = c;
		all_clients_mutex = m;
	}

	void run() {
		while (this->r) {
			sleep(cleaner_time);
			bool changes = false;
			all_clients_mutex->lock();
			for (vector<ClientThread*>::iterator it = clients_threads->begin();
					it != clients_threads->end();) {
				if (IsInactive(*it)) {
					category.notice(
							(*it)->user_name + "@" + (*it)->ip
									+ " is inactive, closing connection.");
					(*it)->stop();
					(*it)->join();
					delete (*it);
					changes = true;
					it = clients_threads->erase(it);
				} else {
					++it;
				}
			}
			//Guardo un nuevo dato de bytes para el grafico
			ofstream ofs;
			ofs.open("./points.txt", ios::app);
			ofs << time(0) - this->start_time << " " << (*stored_bytes) / 1024
					<< endl;
			ofs.close();
			all_clients_mutex->unlock();
		}

	}
};

#endif /* SERVER_CLIENTS_CLEANER_H_ */
